package org.apereo.cas.configuration.model.core.authentication;

import org.apereo.cas.configuration.support.RequiresModule;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;

/**
 * Configuration properties class for cas.authn.policy.
 * 授权规则属性
 * @author Dmitriy Kopylenko
 * @since 5.0.0
 */
@RequiresModule(name = "cas-server-core-authentication", automated = true)
@Getter
@Setter
public class AuthenticationPolicyProperties implements Serializable {

    private static final long serialVersionUID = 2039700004862120066L;

    /**
     * Global authentication policy that is applied when CAS attempts(尝试) to vend(售卖) and validate tickets.
     * Checks to make sure a particular（特殊的） authentication handler has successfully executed and validated credentials.
     * Required handlers are defined per registered service.
     * 当CAS尝试销售和验证票证时应用的全局身份验证策略。
     * 检查以确保特定身份验证处理程序已成功执行并验证了凭据。
     * 每个注册的服务都定义了所需的处理程序。
     */
    private boolean requiredHandlerAuthenticationPolicyEnabled;

    /**
     * Satisfied if any authentication handler succeeds.
     * Allows options to avoid short circuiting and try every handler even if one prior succeeded.
     * 如果任何身份验证处理程序成功，则满足。
     * 允许选项避免短路，并尝试每个处理程序，即使之前的一个处理程序成功。
     */
    private Any any = new Any();

    /**
     * Satisfied if an only if a specified handler successfully authenticates its credential.
     * 仅当指定的处理程序成功验证其凭据时，才满足
     */
    private Req req = new Req();

    /**
     * Satisfied if and only if all given credentials are successfully authenticated.
     * Support for multiple credentials is new in CAS and this handler would
     * only be acceptable in a multi-factor authentication situation.
     * 当且仅当所有给定的凭据都已成功验证时，才满足。
     *
     * 对多个凭据的支持在CAS中是新的，此处理程序将
     *
     * 只有在多因素身份验证的情况下才可接受。
     */
    private All all = new All();

    /**
     * Execute a groovy script to detect authentication policy.
     * 执行groovy 脚本去发现授权规则
     */
    private List<GroovyAuthenticationPolicyProperties> groovy = new ArrayList<>();

    /**
     * Execute a rest endpoint to detect authentication policy.
     * 执行rest endpoint 去发现授权规则
     */
    private List<RestAuthenticationPolicyProperties> rest = new ArrayList<>();

    /**
     * Satisfied if an only if the authentication event is not blocked by a {@code PreventedException}.
     * 如果仅当身份验证事件未被{@code proventedexception}阻止，则满足。
     */
    private NotPrevented notPrevented = new NotPrevented();

    /**
     * Satisfied if an only if the principal has not already authenticated
     * and does not have an sso session with CAS. Otherwise, prevents
     * the user from logging in more than once. Note that this policy
     * adds an extra burden to the ticket store/registry as CAS needs
     * to query all relevant tickets found in the registry to cross-check
     * the requesting username with existing tickets.
     * 仅当主体尚未验证时满足
     * 并且没有与CAS的sso会话。否则，会阻止
     * 用户多次登录。请注意，此策略
     * 根据CAS的需要，给票证存储/注册表增加了额外的负担
     * 查询所有在登记处找到的相关票证进行交叉核对
     * 具有现有票证的请求用户名。
     */
    private UniquePrincipal uniquePrincipal = new UniquePrincipal();

    @Getter
    @Setter
    public static class NotPrevented implements Serializable {

        private static final long serialVersionUID = -4930217018850738715L;

        /**
         * Enables the policy.
         */
        private boolean enabled;
    }

    @Getter
    @Setter
    public static class UniquePrincipal implements Serializable {

        private static final long serialVersionUID = -4930217087310738715L;

        /**
         * Enables the policy.
         */
        private boolean enabled;
    }

    @Getter
    @Setter
    public static class Any implements Serializable {

        private static final long serialVersionUID = 4600357071276768175L;

        /**
         * Enables the policy.
         * 启用策略。
         *
         */
        private boolean enabled = true;

        /**
         * Avoid short circuiting and try every handler even if one prior succeeded.
         * Ensure number of provided credentials does not match the sum of authentication successes and failures
         * *避免短路，并尝试每一个处理程序，即使之前有一个成功。
         *
         * *确保提供的凭据数与身份验证成功和失败的总和不匹配
         */
        private boolean tryAll;
    }

    @Getter
    @Setter
    public static class All implements Serializable {

        private static final long serialVersionUID = 928409456096460793L;

        /**
         * Enables the policy.
         */
        private boolean enabled;
    }

    @Getter
    @Setter
    public static class Req implements Serializable {

        private static final long serialVersionUID = -4206244023952305821L;

        /**
         * Enables the policy.
         */
        private boolean enabled;

        /**
         * Ensure number of provided credentials does not match the sum of authentication successes and failures.
         * 请确保提供的凭据数与身份验证成功和失败的总和不匹配。
         */
        private boolean tryAll;

        /**
         * The handler name which must have successfully executed and validated credentials.
         * 必须已成功执行并验证凭据的处理程序名称。
         */
        private String handlerName = "handlerName";
    }
}
